const enum N {
    /** PI*2 */
    $PI2 = 6.283185307179586,
    /** PI/2 */
    $PI_2 = 1.5707963267948966,
    /** 180/PI */
    $180_PI = 57.29577951308232,
}

/** 二维坐标点 */
export default class Point {

    /** 坐标x */
    x: number
    /** 坐标y */
    y: number

    constructor(cfg: { x?: number, y?: number } = {}) {
        this.x = cfg.x || 0
        this.y = cfg.y || 0
    }

    /** 拷贝 */
    cp() {
        return new Point(this)
    }

    /** 设置坐标 */
    pos(x = 0, y = 0) {
        this.x = x
        this.y = y
    }

    /** 设置为目标点的坐标 */
    posTo(p: Point) {
        this.x = p.x
        this.y = p.y
    }

    /** 到目标点的距离 */
    dis(p: Point) {
        return Math.hypot(p.x - this.x, p.y - this.y)
    }

    /** 朝向目标点的角度 */
    angTo(p: Point) {
        return this.radTo(p) * N.$180_PI
    }

    /** 朝向目标点的弧度 */
    radTo(p: Point) {
        return Math.atan2(p.y - this.y, p.x - this.x)
    }

    /** 朝目标弧度方向移动 */
    move(rad: number, dis: number) {
        this.x += Math.cos(rad) * dis
        this.y += Math.sin(rad) * dis
        return this
    }

    /** 朝目标点移动 */
    moveTo(p: Point, dis: number) {
        return this.move(this.radTo(p), dis)
    }

    /** 点1在点2的象限 0:右上 */
    quadTo(p: Point) {
        let q = Math.floor((p.radTo(this) % N.$PI2) / N.$PI_2)
        return <0 | 1 | 2 | 3>(q < 0 ? q + 4 : q)
    }

    /** 转换到目标点右上象限后的(拷贝)坐标点 */
    toFirstQuad(p: Point) {
        let _p = this.cp()
        switch (_p.quadTo(p)) {
            case 1:
                _p.x = Math.abs(_p.x - p.x)
                break
            case 2:
                _p.x = Math.abs(_p.x - p.x)
                _p.y = Math.abs(_p.y - p.y)
                break
            case 3:
                _p.y = Math.abs(_p.y - p.y)
                break
        }
        return _p
    }

}